﻿/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is tyzoh.jp code.
 *
 * The Initial Developer of the Original Code is Kazutaka Kurihara.
 * Portions created by the Initial Developer are Copyright (C) 2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** */

// SkyDrive Access code by Shinwa

using System;
using System.Windows.Forms;
using PluginInterface;
using System.Collections.Generic;
using System.IO;
using Qurihara.QBasic;
using System.Web;
using System.Collections.Specialized;
using System.Deployment.Application;

using Shiniwa.WindowsLiveHelper;

namespace KotodamaPlugin.SkyDrivePlugin
{
	/// <summary>
	/// Class1 の概要の説明です。
	/// </summary>
	public class SkyDrivePlugin :IPlugin
	{
		private ToolStripMenuItem menuSkyDrive;
        private WLSHelper wlsHelper;

        private MenuItem menuSkyDriveOld;
        private MenuItem sepa;
        private MenuItem filemenu;

        private bool IsLanguage(string twoLetterISOLanguageName)
        {
            return (twoLetterISOLanguageName ==
                System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName);
        }

        // コンストラクタは、ことだま本体プログラムの初期化が終わる前に呼ばれるので、
        // 描画系の初期化（たとえばボタンをメニューに加えるなど）をここで書くとエラーになる。
        // それらはInitialize() に書く。
        public SkyDrivePlugin()
		{
            //menuSkyDrive = new ToolStripMenuItem(Util.IsPropertyTrue("Base.English") ? "Load from SkyDrive" : "SkyDriveから読み込み");
            menuSkyDrive = new ToolStripMenuItem(IsLanguage("en") ? "Load from SkyDrive" : "SkyDriveから読み込み");
            menuSkyDrive.Click += new EventHandler(this.MenuSkyDriveClickEventHandler);

            menuSkyDriveOld = new MenuItem(IsLanguage("en") ? "Load from SkyDrive" : "SkyDriveから読み込み");
            menuSkyDriveOld.Click += new EventHandler(this.MenuSkyDriveClickEventHandler);
            sepa = new MenuItem();
            sepa.Text = "-";

            wlsHelper = new WLSHelper();
		}

		public void MenuSkyDriveClickEventHandler(object o,EventArgs e)
		{
            AskAddress("http://cid-0a2dde87701901c0.skydrive.live.com/self.aspx/%e5%85%ac%e9%96%8b/081030%e6%9c%80%e7%b5%82%e7%94%bb%e9%9d%a2.ks.xml");
        }

        #region asking skydrive address
        private Qurihara.QBasic.TextEntryForm tef;
        private void AskAddress(string defaultName)
        {
            //tef = new TextEntryForm("SkyDriveから読みこみ", Util.IsPropertyTrue("Base.English") ? "Specify a URL for a KOTODAMA file on SkyDrive" : "読み込みたいSkyDrive内のことだまファイルのURLを入力してください。");
            tef = new TextEntryForm("SkyDriveから読みこみ", "URLを入力してください。 - Specify a URL on SkyDrive");
            tef.OutputText = defaultName;
            tef.Closed += new EventHandler(tef_Closed);
            tef.Show();
        }

        private void tef_Closed(object sender, EventArgs e)
        {
            string path = "";
            if (tef != null)
            {
                DialogResult dr = tef.DialogResult;
                if (dr == DialogResult.OK)
                {
                    char[] trm = { '\n' };
                    path = tef.OutputText.TrimEnd(trm);
                }
                tef.Dispose();
                tef = null;

                LoadFromSkyDrive(ConvertUrl2Live(path));
            }
        }
        #endregion

        private string ConvertUrl2Live(string url)
        {
            string[] deli = { "/self.aspx/" };
            string[] p = url.Split(deli, StringSplitOptions.None);
            return "LiveFolders/" + p[p.Length - 1];
        }

        //PopulateFoldersSyncronous();
        //NG FolderContentSyncronous("LiveFolders/公開/081030最終画面.ks.xml");
        //NG FolderContentSyncronous("LiveFolders/%e5%85%ac%e9%96%8b/081030%e6%9c%80%e7%b5%82%e7%94%bb%e9%9d%a2.ks.xml");
        //Good FolderContentSyncronous("LiveFolders/公開");
        //Good FolderContentSyncronous("LiveFolders/%e5%85%ac%e9%96%8b");

        private void LoadFromSkyDrive(string path)
        {
            if(!path.EndsWith(".ks.xml") && !path.EndsWith(".ks")){
                MessageBox.Show("ことだまファイルではないURLです  - Invalid URL.");
                return;
            }

            try
            {
                string dir = Path.GetDirectoryName(path);
                string file = HttpUtility.UrlDecode(Path.GetFileName(path));

                List<LiveItem> contents = wlsHelper.GetFolderContent(dir);
                foreach (LiveItem content in contents)
                {
                    if (content.Name.Equals(file) &&
                        content.ItemType == LiveItemType.Document)
                    {

                        System.IO.MemoryStream stream = content.Content;
                        stream.Seek(0, SeekOrigin.Begin);
                        Host.Kotodama.Presentation.CurrentSlide.Load(stream, "");
                        stream.Close();
                        Host.Kotodama.Control.Invalidate();
                        break;
                    }

                }
            }
            catch
            {
            }
        }

        #region IPlugin Members

        IPluginHost myPluginHost = null;
        //一意の名前を書く
		string myPluginName = "SkyDrivePlugin";
		string myPluginAuthor = "K.Qurihara";
		string myPluginDescription = "test plugin";
		string myPluginVersion = "1.0.0";

        // Initializeは、ことだま本体プログラムの初期化が終わった後、
        // PluginsフォルダにおかれたプラグインDLLを読み込みInitializeしていく。
        public void Initialize()
        {
            //ここが標準のプラグイン関係メニューアイテム格納場所
            try
            {
                ToolStripDropDownButton main = (ToolStripDropDownButton)Host.Kotodama.EnvironmentTable["Base.toolStripDropDownButtonPlugin"];
                main.DropDownItems.Add(menuSkyDrive);
                if (!main.Visible) main.Visible = true;
            }catch{
            }
            try
            {
                Menu.MenuItemCollection mic = (Menu.MenuItemCollection)Host.Kotodama.EnvironmentTable["Base.MenuItems"];
                //filemenu = Qurihara.QBasic.DrawingUtil.FindByName(mic, Util.IsPropertyTrue("Base.English") ? "File" : "ファイル");
                filemenu = Qurihara.QBasic.DrawingUtil.FindByName(mic, "Menu");
                if (filemenu != null)
                {
                    filemenu.MenuItems.Add(sepa);
                    filemenu.MenuItems.Add(menuSkyDriveOld);
                }
            }
            catch
            {
            }


            NameValueCollection query = GetQueryStringParameters();
            string file = HttpUtility.UrlDecode(query["SkyDrive"]);
            if (file != null && file != "") LoadFromSkyDrive(ConvertUrl2Live(file));            
        }
        private NameValueCollection GetQueryStringParameters()
        {
            NameValueCollection nameValueTable = new NameValueCollection();

            if (ApplicationDeployment.IsNetworkDeployed)
            {
                string queryString = ApplicationDeployment.CurrentDeployment.ActivationUri.Query;
                nameValueTable = HttpUtility.ParseQueryString(queryString);
            }

            return (nameValueTable);
        }


        // Disposeはことだま起動中にプラグインの動的なアンロードをするときに用いる。
        // 現在は動的なアンロードはしない方針なので、絶対に必要なわけではないが書くべき。
		void PluginInterface.IPlugin.Dispose()
		{
            try
            {
                ToolStripDropDownButton main = (ToolStripDropDownButton)Host.Kotodama.EnvironmentTable["Base.toolStripDropDownButtonPlugin"];
                main.DropDownItems.Remove(menuSkyDrive);
            }
            catch
            {
            }
            if (filemenu != null)
            {
                filemenu.MenuItems.Remove(sepa);
                filemenu.MenuItems.Remove(menuSkyDriveOld);
            }
        }

        #region no need to edit
        public string Description
		{
			get
			{
				return myPluginDescription;
			}
		}

		public string Author
		{
			get
			{
				return myPluginAuthor;
			}
		}

		public IPluginHost Host
		{
			get
			{
				return myPluginHost;
			}
			set
			{
				myPluginHost = value;
			}
		}
		
		public string Name
		{
			get
			{
				return myPluginName;
			}
		}
		
		public string Version
		{
			get
			{
				return myPluginVersion;
			}
        }
        #endregion

        #endregion

        //#region Synchronous Methods (obsolete)
        //private void PopulateFoldersSyncronous()
        //{
        //    //	get child folders under "LiveFolders". This name is used as top level folders, but hidden to users.
        //    List<LiveItem> collection = wlsHelper.GetLiveFolderCollection("LiveFolders");
        //    //TreeViewItem parentItem = new TreeViewItem();
        //    LiveItem topItem = new LiveItem();
        //    topItem.Name = "LiveFolders";
        //    //parentItem.Header = topItem;
        //    //foreach (LiveItem folder in collection)
        //    //{
        //    //    TreeViewItem item = new TreeViewItem();
        //    //    item.Header = folder;
        //    //    item.Selected += new RoutedEventHandler(item_Selected);
        //    //    parentItem.Items.Add(item);
        //    //}
        //    //FolderView.Items.Add(parentItem);
        //    ////	let's expand the parent by default
        //    //if (collection.Count > 0)
        //    //{
        //    //    parentItem.IsExpanded = true;
        //    //}
        //}

        ///// <summary>
        ///// Syncronous version of populating folder content.
        ///// </summary>
        ///// <param name="path"></param>
        //private void FolderContentSyncronous(string path)
        //{
        //    List<LiveItem> contents = wlsHelper.GetFolderContent(path);
        //    PopulateContentsInGuiThread(contents);
        //}

        //#endregion	//	synchronous methods

        //#region Asynchronous Methods
        ///// <summary>
        ///// Asynchronously populate folders data (via WebRequest).
        ///// </summary>
        //private void PopulateFoldersAsync()
        //{
        //    try
        //    {
        //        AsyncCallback callback = new AsyncCallback(this.PopulateFolderCallback);
        //        HttpWebRequest request = _wlsHelper.SetupLiveGetRequest("LiveFolders");
        //        request.BeginGetResponse(callback, request);
        //    }
        //    catch (WebException ex)
        //    {
        //        System.Diagnostics.Debug.WriteLine(ex.Message);
        //    }

        //}

        ///// <summary>
        ///// Callback method passed to BeginGetResponse (for iterating folders)
        ///// </summary>
        ///// <param name="result"></param>
        //public void PopulateFolderCallback(IAsyncResult result)
        //{
        //    HttpWebRequest request = result.AsyncState as HttpWebRequest;
        //    if (request == null)
        //    {
        //        return;
        //    }
        //    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
        //    if (_wlsHelper != null)
        //    {
        //        List<LiveItem> folderCollection = _wlsHelper.PopulateFoldersFromResponse(response);
        //        this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action<List<LiveItem>>(PopulateFolderInGuiThread), folderCollection);
        //    }
        //}

        ///// <summary>
        ///// Callback method passed to BeginGetResponse (for retrieving contents)
        ///// </summary>
        ///// <param name="result"></param>
        //public void PopulateContentCallback(IAsyncResult result)
        //{
        //    HttpWebRequest request = result.AsyncState as HttpWebRequest;
        //    if (request == null)
        //    {
        //        return;
        //    }
        //    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
        //    if (_wlsHelper != null)
        //    {
        //        List<LiveItem> contents = _wlsHelper.PopulateContentFromResponse(response, _pathCached);
        //        this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action<List<LiveItem>>(PopulateContentsInGuiThread), contents);
        //    }
        //}

        ///// <summary>
        ///// Populate folder data in GUI thread
        ///// </summary>
        ///// <param name="folderCollection"></param>
        //private void PopulateFolderInGuiThread(List<LiveItem> folderCollection)
        //{
        //    //	end animation
        //    if (_readingAnimation != null)
        //    {
        //        _readingAnimation.Stop(this);
        //        ReadingIndicator.Visibility = Visibility.Hidden;
        //    }

        //    TreeViewItem parentItem = new TreeViewItem();
        //    LiveItem topItem = new LiveItem();
        //    topItem.Name = "LiveFolders";
        //    parentItem.Header = topItem;
        //    foreach (LiveItem folder in folderCollection)
        //    {
        //        TreeViewItem item = new TreeViewItem();
        //        item.Header = folder;
        //        item.Selected += new RoutedEventHandler(item_Selected);
        //        parentItem.Items.Add(item);
        //    }
        //    FolderView.Items.Add(parentItem);
        //    //	let's expand the parent by default
        //    if (folderCollection.Count > 0)
        //    {
        //        parentItem.IsExpanded = true;
        //    }
        //}

        ///// <summary>
        ///// Asynchronously populate content data
        ///// </summary>
        ///// <param name="path"></param>
        //private void FolderContentAsync(string path)
        //{
        //    if (_readingAnimation != null)
        //    {
        //        ReadingIndicator.Visibility = Visibility.Visible;
        //        //	clear listview items
        //        ContentPanel.Items.Clear();
        //        _readingAnimation.Begin(this, true);
        //    }

        //    if (_wlsHelper != null)
        //    {
        //        HttpWebRequest request = _wlsHelper.SetupLiveGetRequest(path);
        //        request.BeginGetResponse(new AsyncCallback(PopulateContentCallback), request);
        //    }
        //}

        //#endregion	//	Asynchronous Methods


        /// <summary>
        /// Populate contents in GUI thread.
        /// </summary>
        /// <param name="contents"></param>

//        private void PopulateContentsInGuiThread(List<LiveItem> contents)
//        {
//            ////	end animation
//            //if (_readingAnimation != null)
//            //{
//            //    _readingAnimation.Stop(this);
//            //    ReadingIndicator.Visibility = Visibility.Hidden;
//            //}

//            foreach (LiveItem content in contents)
//            {
//                switch (content.ItemType)
//                {
//                    case LiveItemType.Photo:
//                        {
//                            System.IO.MemoryStream stream = content.Content;
//                            //stream.Seek(0, System.IO.SeekOrigin.Begin);
//                            //BitmapImage source = new BitmapImage();
//                            //source.BeginInit();
//                            //source.CacheOption = BitmapCacheOption.Default;
//                            //source.StreamSource = stream;
//                            //source.EndInit();
//                            //ListViewItem item = new ListViewItem();
//                            //item.Background = new ImageBrush(source);
//                            //double dimension = source.Height / source.Width;
//                            //item.Width = _itemWidth;
//                            //item.Height = item.Width * dimension;
//                            //item.Content = content.Name;
//                            //ContentPanel.Items.Add(item);
//                        }
//                        break;

//                    case LiveItemType.Video:
//                        //	@todo [shiniwa]: maybe use MediaElement here...
//                        System.Diagnostics.Debug.WriteLine("@todo [shiniwa]: Contents include video items");
//                        break;

//                    case LiveItemType.Folder:
//                        {
//                            //ListViewItem item = new ListViewItem();
//                            //ImageBrush brush = App.Current.Resources["folderIconBrush"] as ImageBrush;
//                            //item.Background = brush;
//                            //double dimension = brush.ImageSource.Height / brush.ImageSource.Width;
//                            //item.Width = _itemWidth;
//                            //item.Height = item.Width * dimension;
//                            //item.Content = content.Name;
//                            //ContentPanel.Items.Add(item);
//                        }
//                        break;

//                    default:
//                        {
//                            //	For other data, we'll simply put icon to content view
//                            System.IO.MemoryStream stream = content.Content;
//                            //stream.Seek(0, SeekOrigin.Begin);
//                            //	 just a debugging purpose.
//                            //	Let's save it to temp for debugging.
//#if DEBUG_DUMP
//                            string temp = System.IO.Path.GetTempPath();
//                            string tempPath = System.IO.Path.Combine(temp, "_wlsHelper_debug.tmp");
//                            FileStream debugFile = new FileStream(tempPath, FileMode.Create, FileAccess.Write);
//                            byte[] buffer = new byte[10240];
//                            int length = 0;
//                            do
//                            {
//                                length = stream.Read(buffer, 0, buffer.Length);
//                                debugFile.Write(buffer, 0, length);
//                            } while (length > 0);
//                            debugFile.Close();
//                            stream.Seek(0, SeekOrigin.Begin);
//#endif
//                            //ListViewItem item = new ListViewItem();
//                            //ImageBrush brush = App.Current.Resources["documentIconBrush"] as ImageBrush;
//                            //item.Background = brush;
//                            //double dimension = brush.ImageSource.Height / brush.ImageSource.Width;
//                            //item.Width = _itemWidth;
//                            //item.Height = item.Width * dimension;
//                            //item.Content = content.Name;
//                            //ContentPanel.Items.Add(item);
//                        }
//                        break;
//                }
//            }

//        }

        //#region UI handlers
        ///// <summary>
        ///// even handler when user changed selection on TreeViewItem.
        ///// </summary>
        ///// <param name="sender"></param>
        ///// <param name="e"></param>
        //private void item_Selected(object sender, RoutedEventArgs e)
        //{
        //    System.Diagnostics.Debug.WriteLine("Item_Selected: " + (sender as TreeViewItem).Header.ToString());
        //    _pathCached = SelectedItemPath(sender as TreeViewItem);
        //    if (_pathCached != null)
        //    {
        //        //FolderContentSyncronous(path);
        //        //	use async version instead.
        //        FolderContentAsync(_pathCached);
        //    }
        //}

        //private string SelectedItemPath(TreeViewItem item)
        //{
        //    TreeViewItem current = item;
        //    StringBuilder builder = new StringBuilder(current.Header.ToString());
        //    while (current.Parent != null && current.Parent is TreeViewItem)
        //    {
        //        if (current.Parent != null)
        //        {
        //            string text = (current.Parent as TreeViewItem).Header.ToString();
        //            builder.Insert(0, text + "/");
        //        }
        //        current = current.Parent as TreeViewItem;
        //    }
        //    return builder.ToString();
        //}
        //#endregion

    }
}
